package com.huawei.esdk.uc.sametime.widgets;

import org.apache.log4j.Logger;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;

import com.huawei.esdk.uc.jna.Constants.AccountType;
import com.huawei.esdk.uc.jna.util.StringUtil;
import com.huawei.esdk.uc.sametime.ConstantsDefines;
import com.huawei.esdk.uc.sametime.ConstantsDefines.CallStatus;
import com.huawei.esdk.uc.sametime.international.Messages;
import com.huawei.esdk.uc.sametime.models.Participant;
import com.huawei.esdk.uc.sametime.models.ParticipantList;
import com.huawei.esdk.uc.sametime.services.UCCallService;
import com.huawei.esdk.uc.sametime.services.UCSettingsService;
import com.huawei.esdk.uc.sametime.util.GlobalConfiguration;
import com.huawei.esdk.uc.sametime.util.PluginUtil;
import com.ibm.collaboration.realtime.chatwindow.ChatWindowHandler;
import com.ibm.collaboration.realtime.contacts.search.DirectoryInfo;
import com.ibm.collaboration.realtime.people.Person;

public class CallMemuUtil implements IMenuCreator
{
    private static final String DEFAULTNUMBER = Messages.UNKNOWN;

    private static final String CHATWINDOWPOPUPADDONPACKAGE = "com.huawei.esdk.uc.sametime.chatwindow.chatwindowConvPopupAddOn";

    private static Logger logger = Logger.getLogger(CallMemuUtil.class);

    private Menu menu;

    private ChatWindowHandler chatWindowHandler;

    private boolean isContextMenu = false;

    private boolean isVideo = false;

    private Person selectionPerson;

    public CallMemuUtil(boolean isContextMenu, boolean isVideo)
    {
        this.isContextMenu = isContextMenu;
        this.isVideo = isVideo;
    }

    public CallMemuUtil(ChatWindowHandler chatWindowHandler, boolean isVideo)
    {
        this.chatWindowHandler = chatWindowHandler;
        this.isVideo = isVideo;
    }

    public void setSelectionPerson(Person selectionPerson)
    {
        this.selectionPerson = selectionPerson;
    }

    public void setSelectionPerson(Person[] selectionPersons)
    {
        if (null != selectionPersons && selectionPersons.length > 0)
        {
            this.selectionPerson = selectionPersons[0];
        }
    }

    @Override
    public void dispose()
    {
        if (null != menu)
        {
            menu.dispose();
        }
    }

    @Override
    public Menu getMenu(Control parent)
    {
        if (null != menu)
        {
            menu.dispose();
        }
        menu = new Menu(parent.getShell());

        if (isContextMenu)
        {
            setMenuListen();
        }
        else
        {
            fillMenu();
        }

        return menu;
    }

    @Override
    public Menu getMenu(Menu parent)
    {
        if (null != menu)
        {
            menu.dispose();
        }
        menu = new Menu(parent);

        if (isContextMenu)
        {
            setMenuListen();
        }
        else
        {
            fillMenu();
        }

        return menu;
    }

    private void setMenuListen()
    {
        menu.addMenuListener(new MenuListener()
        {
            @Override
            public void menuHidden(MenuEvent e)
            {
            }

            @Override
            public void menuShown(MenuEvent e)
            {
                Menu menu = (Menu) e.getSource();
                MenuItem[] items = menu.getItems();
                for (int i = 0; items != null && i < items.length; i++)
                {
                    items[i].dispose();
                }
                fillMenu();
            }
        });
    }

    private void fillMenu()
    {
        logger.debug(selectionPerson);
        if (null == selectionPerson)
        {
            return;
        }
        createMenuItem(AccountType.UC_IPPHONE);
        createMenuItem(AccountType.UC_ACCOUNT);
    }

    private void createMenuItem(final int callType)
    {
        String itemTitle = getDisplayName();
        final String callNumber;
        if (AccountType.UC_ACCOUNT == callType)
        {
            itemTitle += Messages.CONTACT_ACCOUNT;
            callNumber = getUCAccount();
        }
        else
        {
            itemTitle += Messages.CONTACT_PHONE;
            callNumber = getTelephone();
        }
        itemTitle += callNumber;

        MenuItem menuItem = new MenuItem(menu, SWT.NONE);
        menuItem.setText(itemTitle);
        menuItem.addSelectionListener(new SelectionAdapter()
        {
            public void widgetSelected(SelectionEvent e)
            {
                addSelectionListener(callType, callNumber);
            }
        });
        isMenuItemEnabled(menuItem);
    }

    private void isMenuItemEnabled(MenuItem menuItem)
    {
        boolean isSamtimeLogin = GlobalConfiguration.getInstance()
                .isSamtimeLogin();
        boolean isUCLogin = GlobalConfiguration.getInstance().isUCLogin();
        boolean isInCall = (CallStatus.end != UCCallService.getCallStatus());
        boolean isVideoOfIPPhone = isVideo
                && ConstantsDefines.IP_PHONE_MODE.equals(UCSettingsService
                        .getPhoneJoinDev());

        if (isSamtimeLogin && isUCLogin && !isInCall && !isVideoOfIPPhone)
        {
            menuItem.setEnabled(true);
        }
        else
        {
            menuItem.setEnabled(false);
        }
    }

    private void addSelectionListener(int callType, String callNumber)
    {
        if (callNumber.equalsIgnoreCase(DEFAULTNUMBER))
        {
            // 通讯录无电话号码呼或无绑定帐号呼叫报错
            String title = Messages.ERROR_TIP;
            String message;
            if (AccountType.UC_ACCOUNT == callType)
            {
                message = Messages.CONTACT_BINDING_ACCOUNT_EMPTY;
            }
            else
            {
                message = Messages.EMPTY_CONTACT_NUM;
            }
            showErrorDialog(title, message);
        }
        else
        {
            // 如果当前没有通话,则可以发起呼叫,否则给出提示
            if (CallStatus.end != UCCallService.getCallStatus())
            {
                MessageDialog.openInformation(Display.getCurrent()
                        .getActiveShell(), Messages.ERROR_TIP,
                        Messages.IS_CALLING);
            }
            else
            {
                // 如果chatWindowHandler不为null,则说明通话时通过聊天窗口发起的
                // 这个时候,需要在聊天窗口底部弹出一个小的扩展区域
                if (null != chatWindowHandler)
                {
                    GlobalConfiguration.getInstance().setVideo(isVideo);
                    GlobalConfiguration.getInstance().setConf(false);
                    createChatPopupArea();
                }
                else
                {
                    Participant participant = new Participant();
                    ParticipantList participantList = new ParticipantList();

                    participant.setContactId(selectionPerson.getContactId());
                    participant.setNumber(callNumber);
                    participant.setCallNumType(callType);

                    participantList.addparticipants(participant);
                    try
                    {
                        EsdkUCConvWindow window = EsdkUCConvWindow
                                .getInstance();
                        window.createUCConvWindow(participantList);
                        window.makeCall(isVideo);
                    }
                    catch (Exception exception)
                    {
                        exception.printStackTrace();
                        logger
                                .error("an error occur when make call,and error msg is: "
                                        + exception.getMessage());
                    }
                }

            }

        }
    }

    private void createChatPopupArea()
    {
        chatWindowHandler.createPopupMessageArea(CHATWINDOWPOPUPADDONPACKAGE,
                300);
    }

    private void showErrorDialog(String title, String message)
    {
        MessageDialog.openError(menu.getShell(), title, message);
    }

    private String getUCAccount()
    {
        // String account = DEFAULTNUMBER;
        // 在之后的account赋值中，不管附什么值，总是会覆盖DEFAULTNUMBER，所以account默认赋值为null
        String account = null;
        String contactID = getContactID();
        logger.info("getUCAccount, and contactID is: " + contactID);
        if (!StringUtil.isEmptyStr(contactID))
        {
            account = PluginUtil.getUCAccountFromContactID(contactID);
        }
        else
        {
            account = DEFAULTNUMBER;
        }
        logger.info("getUCAccount, and account is: " + account);
        return account;
    }

    private String getDisplayName()
    {
        return selectionPerson.getDisplayName();
    }

    private String getTelephone()
    {
        logger.debug("getTelephone");
        return getDirectoryAttribute(DirectoryInfo.TELEPHONE);

        // /*
        // * 此处先使用呼叫设置里面的呼叫号码1字段,待sametiime与uc做的账号同步机制确定且环境准备好之后再做修改
        // */
        // IPreferenceStore store = EsdkPluginActivator.getDefault()
        // .getPreferenceStore();
        // String toCallNum = store.getString(PreferenceConstants.P_NUMBER_1);
        //
        // logger.info("toCallNum = " + toCallNum);
        //
        // if (null == toCallNum || toCallNum.isEmpty())
        // {
        // toCallNum = DEFAULTNUMBER;
        // }
        // return toCallNum;
    }

    // private String getEmail()
    // {
    // return getDirectoryAttribute(DirectoryInfo.MAIL_ADDRESS);
    // }

    private String getContactID()
    {
        return selectionPerson.getContactId();
    }

    private String getDirectoryAttribute(String name)
    {
        logger.debug("getDirectoryAttribute | name : " + name);

        String number = DEFAULTNUMBER;
        DirectoryInfo dirInfo = selectionPerson.getDirectoryInfo();
        if (null != dirInfo)
        {
            String temp = (String) dirInfo.get(name);
            if (null != temp)
            {
                number = temp;
            }
        }
        logger.debug("getDirectoryAttribute | name : " + name + ", result : "
                + number);
        return number;
    }
}
